<?php

namespace app\common\model;

use basic\ModelBasic;
use app\common\model\user\UserGoldsBill;

class User extends ModelBasic
{
	use \traits\ModelTrait;

	const STATUS_VALID = 1;

    const TOKEN_KEY = 'ftx@guolv@2024';

    public static $status = [
        0 => '已禁用',
        1 => '正常',
        2 => '已注销'
    ];

	public static $gender = [
		0 => '保密',
		1 => '男',
		2 => '女',
	];

    const LOGIN_FIELD = 'u.uid,u.usn,u.status,u.avatar,u.mobile,u.nickname,u.mobile,u.mate_mobile,u.mate_mobile2,u.full_name,u.is_idcheck,u.birthday,u.tour_perfer,u.tour_target,u.golds,u.openid,u.level_id';

	/**
	 * 创建密码盐值
	 * @DateTime 2021-07-28
	 * @param    [type]           $pkg_id [description]
	 */
	public static function create_salt ()
	{
		$gene = str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');

		$start = mt_rand( 0, strlen($gene) - 6 );

		return substr($gene , $start , 6);
	}

	/**
	 * 创建密码
	 * @param  [type] $plain_password 明文密码
	 * @param  [type] $salt           [description]
	 * @return [type]                 [description]
	 */
	public static function create_password ($plain_password , $salt)
	{
		return sha1( sha1($plain_password) . $salt );
	}

	/**
	 * [create_password description]
	 * @param  [type] $plain_password   明文密码
	 * @param  [type] $encrypt_password 密文密码
	 * @param  [type] $salt             加密盐值
	 * @return [type]                 [description]
	 */
	public static function verify_password ($plain_password , $salt , $encrypt_password)
	{
		return static::create_password($plain_password , $salt) == $encrypt_password;
	}

	/**
	 * 设置where条件
	 * @Author   FW
	 * @DateTime 2021-01-12
	 * @Email    123763712@qq.com
	 * @param    [type]           $where [description]
	 * @param    string           $alias [description]
	 * @param    [type]           $model [description]
	 */
	public static function setWhere($where,$alias='m',$model=null)
    {
        $model = $model===null ? new self() : $model;

        $model->alias($alias);

        if ( isset($where['status']) && $where['status'] != '' ) {
            $model->where( sprintf('%s.status = %d' , $alias , $where['status']));
        }

        if ( isset($where['sales_admin_id']) && $where['sales_admin_id'] > 0 ) {
            $model->where( sprintf('%s.sales_admin_id = %d' , $alias , $where['sales_admin_id']));
        }

        if ( isset($where['processon_ignore_days']) && $where['processon_ignore_days'] > 0 ) {
            // 15 30 60
            $days = array_keys(CustomerProcesson::$groups);
            if ( in_array($where['processon_ignore_days'] , $days) ) {
                $model->where(sprintf("(DATEDIFF(NOW(), %s.last_processon_time) >= %d) OR (%s.last_processon_time is null)" , $alias , $where['processon_ignore_days'], $alias));
            }
        }

        if ( isset($where['keyword']) && $where['keyword'] != '' ) {
            $keyword = $where['keyword'];
            $model->where(sprintf("%s.full_name|%s.mobile" , $alias, $alias) , 'LIKE' , "%{$keyword}%");
        }


        if ( isset($where['full_name']) && $where['full_name'] != '' ) {
            $full_name = $where['full_name'];
            $model->where(sprintf("%s.full_name|%s.nickname" , $alias, $alias) , 'LIKE' , "%{$full_name}%");
        }


        if ( isset($where['mobile']) && $where['mobile'] != '' ) {
            $model->where(sprintf("%s.mobile",$alias) , 'LIKE' , '%'.$where['mobile'].'%');
        }

        if ( isset($where['mate_mobile']) && $where['mate_mobile'] != '' ) {
            $mate_mobile = trim($where['mate_mobile']);
            $model->where('(' . $alias.'.mate_mobile LIKE "%' . $where['mate_mobile'] . '%") OR (' . $alias . '.mate_mobile2 LIKE "%' . $where['mate_mobile'] . '%")' );
        }

        if ( isset($where['register_date']) && $where['register_date'] != '' ) {
           $model->where(sprintf("%s.register_date",$alias) , 'LIKE' , '%'.$where['register_date'].'%');
        }

        if ( isset($where['tour_perfer']) && $where['tour_perfer'] != '' ) {
           $model->where(sprintf("%s.tour_perfer",$alias) , 'LIKE' , '%'.$where['tour_perfer'].'%');
        }
        if ( isset($where['tour_target']) && $where['tour_target'] != '' ) {
           $model->where(sprintf("%s.tour_target",$alias) , 'LIKE' , '%'.$where['tour_target'].'%');
        }

        return $model;
    }

    /**
     * 列表
     * @Author   FW
     * @DateTime 2020-09-24
     * @Email    123763712@qq.com
     * @param    [type]
     * @return   [type]
     */
    public static function getList($where)
    {
    	$count = self::setWhere($where)->count();
    	$data  = [];
    	if ( $count == 0 ) {
    		return compact('data','count');
    	}

        $data=self::setWhere($where,'m')
        ->field("m.uid,m.usn,m.avatar,m.mobile,m.mate_mobile,m.mate_mobile2,m.full_name,m.nickname,m.status,DATE_FORMAT(m.register_date,'%y年%m月%d日') as register_date,m.level_id,m.gender,m.last_time,m.golds,m.remark,m.is_idcheck,m.birthday,m.tour_perfer,m.tour_target,m.sales_admin_id,m.spread_suid,m.last_processon_time,m.cus_from,m.wheregone,sales.full_name as sales_name,lev.grade_type,lev.discount,ifnull(unfollow.id,0) as unfollow_record_id,ifnull(unfollow.record_time,'NONE') as unfollow_record_time,ifnull(unfollow.handle_time,'') as unfollow_handle_time,ifnull(unfollow.handle_status,0) as unfollow_handle_status")
        ->join('__USER_LEVEL__ lev' , 'm.level_id = lev.id','left')
        ->join('__SYSTEM_ADMIN__ adm' , 'm.sales_admin_id = adm.id','left')
        ->join('__TEACHER_INFO__ sales' , 'adm.id = sales.admin_id','left')
        ->join('__UNFOLLOW_RECORD__ unfollow' , 'm.uid = unfollow.uid','left')
        ->with('idcard')
        ->with('address')
        ->page( $where['page'] ?? 1, $where['limit'] ?? 10)
        ->order('m.register_date desc')
        ->select();

        if ( !empty($data) ) {
        	$data = $data->toArray();
        	$data = static::process_list($data);
        }

        return compact('data','count');
    }

    /**
     * 用户实名信息
     * @Author   FW
     * @DateTime 2024-08-21
     * @Email    123763712@qq.com
     * @return   [type]           [description]
     */
    public function idcard()
    {
        return $this->hasOne('\app\common\model\user\UserIdcard' , 'uid');
    }

    /**
     * 用户地址列表
     * @Author   FW
     * @DateTime 2024-08-21
     * @Email    123763712@qq.com
     * @return   [type]           [description]
     */
    public function address()
    {
        return $this->hasMany('\app\common\model\user\UserAddress' , 'uid');
    }

    /**
     * 处理列表数据
     * @Author   FW
     * @DateTime 2021-01-12
     * @Email    123763712@qq.com
     * @param    array            $list [description]
     * @return   [type]                 [description]
     */
    public static function process_list (array $list)
    {
        foreach ($list as &$item ) {
        	$item['status_display'] = static::$status[$item['status']] ?? '-';
        	$item['gender_display'] = static::$gender[$item['gender']] ?? '-';
            $item['last_time_display'] = date('Y年m月d日',strtotime($item['last_time']));
            $item['order_total_amt'] = Order::where('pay_status=1')->where('uid',$item['uid'])->sum('order_amt');

            ## 未跟进天数状态
            $item['processon_ignore_days'] = 365;
            $item['processon_ignore_text'] = '从未跟进';
            $item['processon_records'] = [];
            if ( !empty($item['last_processon_time']) ) {
                $processon = CustomerProcesson::calcIgnoreDays($item['last_processon_time']);
                $item['processon_ignore_days'] = $processon['days'] ?? 0;
                $item['processon_ignore_text'] = $processon['text'] ?? '跟进良好';
                $item['processon_records'] = CustomerProcesson::where('uid',$item['uid'])->order('ontime DESC')->select();
            }

            $item['birthdayb'] = 0;
            $item['birthdayc'] = 0;
            $item['birthdayb_text'] = '未发送';
            $item['birthdayc_text'] = '未发送';
            if ( $item['birthday'] != '0000-00-00' ) {
                if ( empty($item['spread_suid']) ) $item['spread_suid'] = TeacherInfo::where('admin_id',$item['sales_admin_id'])->value('uid');
                $item['birthdayb'] = Message::where([
                    'mtype'      => Message::MSG_TYPE_BIRTHDAYB,
                    'mgap_days'  => 1,
                    'uid'        => $item['spread_suid'],
                ])->count() > 0 ? 1 : 0;
                if ( $item['birthdayb'] > 0 ) {
                    $item['birthdayb_text'] = '已发送';
                }

                $item['birthdayc'] = Message::where([
                    'mtype'      => Message::MSG_TYPE_BIRTHDAYC,
                    'mgap_days'  => 1,
                    'uid'        => $item['uid'],
                ])->count() > 0 ? 1 : 0;
                if ( $item['birthdayc'] > 0 ) {
                    $item['birthdayc_text'] = '已发送';
                }
            }

        }
        return $list;
    }

    /**
     * 创建新用户
     * @Author   FW
     * @DateTime 2021-09-06
     * @Email    123763712@qq.com
     * @param    array            $post [description]
     * @return   [type]                 [description]
     */
    public static function create_new_user ( array $post )
    {
        $user                 = new self;
        $user->salt           = self::create_salt();
        $user->usn            = self::calUserSerialNo();
        $user->avatar         = $post['avatar'] ?? (\think\Env::get('SYSTEM.SITE_URL') . '/public/static/images/avatar.png');
        $user->mobile         = $post['mobile'] ?? '';
        $user->mate_mobile    = $post['mate_mobile'] ?? '';
        $user->mate_mobile2   = $post['mate_mobile2'] ?? '';
        $user->pwd            = self::create_password($user->mobile,$user->salt);
        $user->nickname       = $post['nickname'] ?? '';
        $user->full_name      = $post['full_name'] ?? '';

        if( !$user->nickname ) {
            $user->nickname = '微信用户';
            if ($user->full_name) $user->nickname = $user->full_name;
        }

        $user->remark         = $post['remark'] ?? '';
        $user->cus_from       = $post['cus_from'] ?? '';
        $user->wheregone      = $post['wheregone'] ?? '';
        $user->is_idcheck     = $post['is_idcheck'] ?? 0;
        $user->register_ip    = request()->ip();
        $user->register_date  = date('Y-m-d H:i:s');
        $user->status         = $post['status'] ?? 1;
        $user->last_time      = date('Y-m-d H:i:s');
        $user->last_ip        = request()->ip();
        $user->openid         = $post['openid'] ?? md5($user->mobile . $user->register_ip);
        $user->unionid        = $post['unionid'] ?? md5($user->openid);
        $user->level_id       = $post['level_id'] ?? 0;
        $user->birthday       = $post['birthday'] ?? '';
        $user->tour_perfer    = $post['tour_perfer'] ?? '';
        $user->tour_target    = $post['tour_target'] ?? '';
        $user->spread_uid     = $post['spread_uid'] ?? 0;
        $user->spread_suid    = $post['spread_suid'] ?? 0;
        $user->sales_admin_id = $post['sales_admin_id'] ?? 0;
        // 自动获取该销售经理绑定的管理员ID：用户作为客户归属于该销售-管理员名下
        if ( $user->spread_suid > 0 && !$user->sales_admin_id ) {
            $user->sales_admin_id = self::calcSalesAdminId($user->spread_suid);
        }

        $res = $user->save();
        if ( !$res ) throw new \Exception('用户注册失败');

        // 如果有推广会员ID，奖励金币。适用于普通用户和领队推广
        if ( $user->spread_uid > 0 ) {
            $res = UserGoldsBill::add($amt = 10, $stype = UserGoldsBill::STYPE_INVITAE_REG , $user->spread_uid);
            if ( $res === false ) throw new \Exception('Error 10093');
        }

        return $user;
    }

    /**
     * 生成TOKEN令牌
     * @Author   FW
     * @DateTime 2024-03-13
     * @Email    123763712@qq.com
     * @param    [type]           $uid [description]
     * @return   [type]                [description]
     */
    public static function create_token($uid)
    {
        return substr(sha1(static::TOKEN_KEY . $uid),2,36);
    }

    /**
     * 设置登录登录信息
     * @param [type] $user_info [description]
     */
    public static function set_login ($user_info)
    {
        if ( is_object($user_info) ) {
            $user_info->last_time = date('Y-m-d H:i:s');
            $user_info->last_ip   = request()->ip();
            $user_info->save();

            $user_info = $user_info->toArray();
        }

        if ( isset($user_info['salt']) ) unset($user_info['salt']);
        if ( isset($user_info['pwd']) ) unset($user_info['pwd']);

        $user_info['token'] = static::create_token($user_info['uid']);

        ## 检查用户-销售-管理员绑定关系
        $user_info['rel_admin_id'] = $user_info['rel_sales_id'] = 0;
        $saler = TeacherInfo::where('uid',$user_info['uid'])->field('id,admin_id')->find();
        if ( !empty($saler) ) {
            $user_info['rel_admin_id'] = $saler->admin_id;
            $user_info['rel_sales_id'] = $saler->id;
        }

        ## 检查用户会员购买情况
        $user_info['prime_info'] = static::userPrimeInfo($user_info['uid']);

        \think\Cache::set($user_info['token'],$user_info);
        return $user_info;
    }

    /**
     * 获取用户会员等级情况
     *status:0 未获得-立即开卡  1 已获得-可升级 2 已获得-最高等级 3已获得-已过期
     * @Author   FW
     * @DateTime 2024-04-10
     * @Email    123763712@qq.com
     * @param    integer          $uid      [description]
     * @return   [type]                     [description]
     */
    public static function userPrimeInfo($uid)
    {
        $level_record = UserLevel::field("DATE_ADD(DATE(NOW()), INTERVAL days DAY) as expire_date,id,grade_type,rights_info,0 as status")->where('status',1)->order('grade_type ASC')->find();

        // 当前会员等级
        $currenLevelId = UserLevel::alias('ul')->join('__USER__ u','ul.id=u.level_id')->where('u.uid',$uid)->where('ul.status',1)->value('id');
        if ( $currenLevelId > 0 ) {
            $level_record = UserLevelRecords::alias('m')
            ->field('m.expire_date,ul.id,ul.grade_type,ul.rights_info,1 as status')
            ->join('__USER_LEVEL__ ul','m.level_id=ul.id')
            ->where(['m.uid'=>$uid,'m.level_id'=>$currenLevelId])
            ->where('m.is_paid',1)
            ->order('m.expire_date DESC') //取用户已获得过期时间最久远的一条
            ->find();

            ## 如果过期则直接告知前台
            if ( strtotime($level_record->expire_date) < time() ) {
                $level_record->status = 3;
            }
            ## 没有过期则检查是否可以升到更高一级
            else{
                $next = UserLevel::where('grade_type','gt',$level_record->grade_type)->where('status',1)->count();
                if ( !$next ) $level_record->status = 2;
            }
        }
        $level_record->grade_type_display = UserLevel::$grade_type[$level_record->grade_type]??'-';
        $level_record->expire_date_format = date('Y年m月d日',strtotime($level_record->expire_date));

        return $level_record;
    }

    /**
     * 获取当前登录用户信息
     * @return [type] [description]
     */
    public static function get_login ( $token )
    {
		return \think\Cache::get($token);
    }

    /**
     * 清除登录
     * @return [type] [description]
     */
    public static function clear_login ( $token )
    {
        return \think\Cache::rm($token);
    }

    /**
     * 微信小程序unionID登录
     * @param $spread_suid 销售经理UID
     * @param $spread_uid  推广会员UID
     * @return [type] [description]
     */
    public static function wechat_login ( $wechatUser , $spread_suid = 0 , $spread_uid = 0 )
    {
        if ( isset($wechatUser['openid']) ) {
            if ( isset($wechatUser['unionid']) ) {
                $user = self::alias('u')->field(self::LOGIN_FIELD)
                    ->where('u.unionid', $wechatUser['unionid'])
                    ->find();
            } else {
                $user = self::alias('u')->field(self::LOGIN_FIELD)
                ->where('u.openid', $wechatUser['openid'])
                ->find();
            }
        }

        if ( !empty($user) ) if ( $user->status != 1 ) throw new \Exception('用户已被禁用');

        if ( empty($user) ) {
            $new_user = [
                'unionid'    => $wechatUser['unionid'] ?? '',
                'openid'     => $wechatUser['openid'] ?? '',
                'spread_suid'=> $spread_suid,
                'spread_uid' => $spread_uid,
            ];
            $user = static::create_new_user($new_user);
        }

        return static::set_login($user);
    }

    /**
     * 计算销售经理绑定的管理员ID
     * @Author   FW
     * @DateTime 2024-03-25
     * @Email    123763712@qq.com
     * @param    [type]           $uid [description]
     * @return   [type]                [description]
     */
    public static function calcSalesAdminId($uid)
    {
        $saler = TeacherInfo::where('uid',$uid)->field('id,admin_id')->find();
        if ( !empty($saler) ) {
            return $saler->admin_id;
        }
        return 0;
    }

    /**
     * 计算新增会员的序列编号
     * @Author   FW
     * @DateTime 2024-12-01
     * @Email    123763712@qq.com
     * @param    [type]           $uid [description]
     * @return   [type]                [description]
     */
    public static function calUserSerialNo()
    {
        $length   = 6;
        $serialNo = (int)static::max('usn');
        $serialNo++;

        $serialNo = str_pad($serialNo, $length, '0', STR_PAD_LEFT);

        return $serialNo;
    }

    /**
     * 删除用户
     * @Author   FW
     * @DateTime 2024-08-21
     * @Email    123763712@qq.com
     * @param    [type]           $uid [description]
     * @return   [type]                [description]
     */
    public static function deleteUser($uid)
    {
        ## 01 删除用户主数据
        $res = static::where('uid' , $uid)->delete();
        if ( $res === false ) throw new \Exception('删除失败10001');

        ## 02 删除用户优惠券
        $res = CouponRecords::where('uid' , $uid)->delete();
        if ( $res === false ) throw new \Exception('删除失败10002');

        ## 03 删除用户跟进记录
        $res = CustomerProcesson::where('uid' , $uid)->delete();
        if ( $res === false ) throw new \Exception('删除失败10003');

        ## 04 删除用户订单
        $res = Order::where('uid' , $uid)->delete();
        if ( $res === false ) throw new \Exception('删除失败10004');

        ## 05 删除用户订单日志
        $res = OrderLogs::where('uid' , $uid)->delete();
        if ( $res === false ) throw new \Exception('删除失败10005');

        ## 06 删除用户签到记录
        $res = SignTaskRecords::where('uid' , $uid)->delete();
        if ( $res === false ) throw new \Exception('删除失败10006');

        ## 07 删除用户会员开通记录
        $res = UserLevelRecords::where('uid' , $uid)->delete();
        if ( $res === false ) throw new \Exception('删除失败10007');

        ## 08 删除用户会员登录记录
        $res = UserLoginRecords::where('uid' , $uid)->delete();
        if ( $res === false ) throw new \Exception('删除失败10008');

        ## 09 删除用户账单记录
        $res = user\UserGoldsBill::where('uid' , $uid)->delete();
        if ( $res === false ) throw new \Exception('删除失败10009');

        ## 10 删除用户身份证
        $res = user\UserIdcard::where('uid' , $uid)->delete();
        if ( $res === false ) throw new \Exception('删除失败10010');

         ## 11 删除用户地址
        $res = user\UserAddress::where('uid' , $uid)->delete();
        if ( $res === false ) throw new \Exception('删除失败10011');

        return true;
    }
}//Class End
